#!/bin/bash

# What is our domain
DOMAIN="dyn.myzone.de"

# Where is the zonefile for that domain
ZONEFILE="/etc/bind/dyn.myzone.de"

# These credentials are needed at the Fritz!Box side
# (user and pass in DynDNS config)
MGRUSER="dyndnsuser"
MGRPASS="dyndnspass"

# Fritz!Box access data WEBUSER/WEBPASS: Remote access, UIPASS: Web interface
FRITZWEBUSER="fritzweb"
FRITZWEBPASS="fritzweb"
FRITZUIPASS="fritzui"

# hostnames and their corresponding mac addresses, divided by %
HOSTMAC="mydesktop%00:00:00:00:00:00 mylaptop%11:11:11:11:11:11"

# hostname for the Fritz!Box itself
BOXNAME="fritzbox"

# Which ports to open with 6tunnel and to which hosts?
# Format: LOCALPORT:HOSTNAME:REMOTEPORT
# (example opens ports 10122 and 10123 to the both ports 22 on two machines)
FORWARDS="10122:mydesktop:22 10123:mylaptop:22"

# Where do we log to?
LOGFILE="/var/log/fritz6dns"

####
####
#### END OF CONFIGURATION
####
####

function update {

  # kill old tunnels
  killall 6tunnel

  # read the Fritz!Box IPV6 from the parameters
  BOXIP6="$1"

  # Create a new zonefile with only the old header
  TMPZONEFILE="`mktemp`"
  head -n11 $ZONEFILE > $TMPZONEFILE

  # Insert the Fritz!Box data
  echo "$BOXNAME AAAA $BOXIP6" >> $TMPZONEFILE

  # get the prefix from the Fritz!Box
  # some code modified from http://www.wehavemorefun.de/fritzbox/Anrufliste_von_der_Box_holen
  # under GFDL 1.2
  ChallengeXML=`wget -q -O - --no-check-certificate "https://$FRITZWEBUSER:$FRITZWEBPASS@[$1]/cgi-bin/webcm?getpage=../html/login_sid.xml" 2>/dev/null| grep Challenge`
  Challenge=`echo $ChallengeXML | awk '{match($0,/>[^<>]+</); print substr($0,RSTART+1,RLENGTH-2)}'`
  CPSTR="$Challenge-$FRITZUIPASS"
  MD5=`echo -n $CPSTR | iconv -f ISO8859-1 -t UTF-16LE | md5sum -b | awk '{print substr($0,1,32)}'`
  RESPONSE="$Challenge-$MD5"
  POSTDATA="login:command/response=$RESPONSE&getpage=../html/de/menus/menu2.html"
  SID=`wget -q -O - --no-check-certificate --post-data="$POSTDATA" "https://$FRITZWEBUSER:$FRITZWEBPASS@[$1]/cgi-bin/webcm" 2>/dev/null| grep "name=\"sid\"" | head -1 | awk '{match($0,/value="[^"]+"/); print substr($0,RSTART+7,RLENGTH-8)}'`
  wget -q -O /dev/null --no-check-certificate "https://$FRITZWEBUSER:$FRITZWEBPASS@[$1]//cgi-bin/webcm?sid=$SID&getpage=..%2Fhtml%2Fde%2Fmenus%2Fmenu2.html&errorpage=..%2Fhtml%2Fde%2Fmenus%2Fmenu2.html&var%3Apagename=foncalls&var%3Aerrorpagename=foncalls&var%3Amenu=home&var%3Apagemaster=&var%3Aactivtype=pppoe&var%3AtabInetstat=0&var%3Aweckernr=&logger%3Asettings%2Ffilter=2"
  prefix=`wget -q -O- --no-check-certificate "https://$FRITZWEBUSER:$FRITZWEBPASS@[$1]/home/home.lua?sid=$SID" | sed -e "s|<|\n<|g" | grep IPv6-Präfix | rev | cut -f1 -d\  | rev`

  # calculate host entries and add entries to the zonefile
  for hostmac in $HOSTMAC; do
    read hostname mac <<<$(IFS="%"; echo $hostmac)
    address=`ipv6calc --in prefix+mac --action prefixmac2ipv6 $prefix $mac --out ipv6addr | cut -f1 -d/`
    echo $hostname AAAA $address >> $TMPZONEFILE
  done

  # Update the serial number in the temporary zonefile
  SERIALLINE="`cat $ZONEFILE | grep ";serial"`"
  SERIALDATE="`echo $SERIALLINE | cut -c1-8`"
  SERIALNUMB="`echo $SERIALLINE | cut -c9-10`"
  TODAY="`date +%Y%m%d`"
  if [ "$SERIALDATE" == "$TODAY" ]; then
    SERIALNUMB="`expr $SERIALNUMB + 1`"
    if [ $SERIALNUMB -lt 10 ]; then
      SERIALNUMB="0$SERIALNUMB"
    fi
    NEWSERIAL="${SERIALDATE}${SERIALNUMB}"
  else
    NEWSERIAL="${TODAY}01"
  fi
  sed -i "s|$SERIALLINE|$NEWSERIAL ;serial|g" $TMPZONEFILE

  # move the zonefile and restart the bind server
  mv $TMPZONEFILE $ZONEFILE
  chmod a+r $ZONEFILE
  /etc/init.d/bind9 reload > /dev/null 2> /dev/null

  # give bind a bit of time to start
  sleep 3

  # re-instate all tunnels
  for forward in $FORWARDS; do
    read localport hostname remoteport <<<$(IFS=":"; echo $forward)
    /usr/bin/6tunnel ${localport} ${hostname}.${DOMAIN} $remoteport 2> /dev/null
  done

  # write the log
  echo "${NEWSERIAL}:${BOXIP6}" >> ${LOGFILE} 

  # tell the Fritz!Box that everything is fine
  echo "good"
}

function credentials {
  # if you change this, also change .htaccess!
  htpasswd -cbd /etc/fritz6dnspass $MGRUSER $MGRPASS
}

$1 $2
